package com.atguigu.mybatis021.excptionhandler;

import com.atguigu.mybatis021.excption.BusinEexction;
import com.atguigu.mybatis021.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.javassist.NotFoundException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.List;

@RestControllerAdvice
@Slf4j
public class GloableExceptionHandler {
    @ExceptionHandler(ArithmeticException.class)
    public R ArithmeticExceptionHandler(Exception e) {
        log.error("出现算数异常");
        return R.error(500,e.getMessage() + e.getCause()) ;
    }

    @ExceptionHandler(NotFoundException.class)
    public R fileNotFoundExceptionHandler(Exception e) {
        log.error("出现文件未找到异常");
        return R.error(700,e.getMessage() + e.getCause()) ;
    }

    @ExceptionHandler(BusinEexction.class)
    public R BusinEexctionHandler(Exception e) {
        log.error("出现业务异常");
        return R.error(e.getMessage()+ e.getCause()) ;
    }

    // 处理方法参数校验异常
    /**
     * 处理MethodArgumentNotValidException异常
     * 当方法参数校验失败时，Spring会抛出MethodArgumentNotValidException异常
     * 该方法用于捕获该异常并返回错误信息
     *
     * @param e MethodArgumentNotValidException类型的异常对象，包含校验失败的信息
     * @return 返回R对象，包含错误代码、错误消息和具体的错误字段及消息
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {

        // 获取校验结果
        BindingResult bindingResult = e.getBindingResult();
        // 创建一个HashMap用于存储错误字段和对应的错误消息
        HashMap<String, String> map = new HashMap<>();
        // 获取所有字段错误
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        // 如果存在字段错误
        if (fieldErrors.size() > 0) {
            // 遍历所有字段错误
            fieldErrors.forEach(fieldError -> {
                // fieldError 代表错误字段，它身上可以获取错误字段和错误消息
                String field = fieldError.getField();//错误字段
                String defaultMessage = fieldError.getDefaultMessage();//错误的消息
                // 将错误字段和错误消息存入map
                map.put(field, defaultMessage);
            });
            // 返回错误信息，包括错误代码、错误消息和具体的错误字段及消息
            return R.error(500,"校验失败" ,map);
        }
        // 如果不存在字段错误，返回异常信息和原因
        return R.error(500, e.getMessage() + e.getCause());
    }


    @ExceptionHandler(Exception.class)
    public R exceptionHandler(Exception e) {
        log.error("出现其他未知异常");
        log.error(e.getClass().getName());
//        System.out.println("出现其他未知异常");
//        System.out.println(e.getClass());
        return R.error(666, e.getMessage() + e.getCause());
    }
}
